/*
 * @Author: yanjikun
 * @Date: 2021-06-22 17:00:45
 * @LastEditors: yanjikun
 * @LastEditTime: 2022-06-20 11:15:28
 * @Description: file content
 */

import { CACHE_CIPHER } from '@/settings/cipherSetting'
import { AesEncryption } from './cipher'

// 默认缓存期限为7天
const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7

interface CreateStorageConfigType {
  /**名称前缀 */
  prefixKey?: string
  /**本地存储类型 */
  storage?: Storage
  /**是否加密 */
  isEncrypt?: boolean
}
/**
 * @description: 创建本地缓存对象
 * @param {*}
 * @author: yanjikun
 */
export const createStorage = ({
  prefixKey = '',
  storage = localStorage,
  isEncrypt = true,
}: CreateStorageConfigType = {}) => {
  const encryption = new AesEncryption(CACHE_CIPHER)
  const Storage = class {
    private storage = storage
    private prefixKey?: string = prefixKey
    private getKey(key: string) {
      return `${this.prefixKey}${key}`.toUpperCase()
    }
    /**
     * @description: 设置缓存
     * @param {string} key 缓存的key
     * @param {any} value 缓存的值
     * @param {number} expire 缓存的期限
     * @return {*}
     * @author: yanjikun
     */
    set(key: string, value: any, expire: number | null = DEFAULT_CACHE_TIME): void {
      const stringData = JSON.stringify({
        value,
        expire: expire !== null ? new Date().getTime() + expire * 1000 : null,
      })
      this.storage.setItem(
        this.getKey(key),
        isEncrypt ? encryption.encryptByAES(stringData) : stringData,
      )
    }
    /**
     * @description: 读取缓存
     * @param {string} key 缓存的key
     * @param {any} def 默认值
     * @return {*} 缓存的值
     * @author: yanjikun
     */
    get<T = any>(key: string, def: any = null): T {
      const item = this.storage.getItem(this.getKey(key))
      if (item) {
        try {
          const data = JSON.parse(isEncrypt ? encryption.decryptByAES(item) : item)
          const { value, expire } = data
          if (expire === null || expire >= Date.now()) {
            return value
          }
          this.remove(this.getKey(key))
        } catch (error) {
          return def
        }
      }
      return def
    }
    /**
     * @description: 从缓存移除某项
     * @param {string} key 移除的key
     * @return {*}
     * @author: yanjikun
     */
    remove(key: string): void {
      this.storage.removeItem(this.getKey(key))
    }
    /**
     * @description: 清空缓存
     * @author: yanjikun
     */
    clear(): void {
      this.storage.clear()
    }
  }
  return new Storage()
}

export const storage = createStorage()

export default Storage
